package org.test4j.mock.faking.fluent;

import lombok.Getter;
import org.test4j.mock.faking.meta.MethodId;
import org.test4j.mock.faking.util.TypeUtility;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * key: method description
 * value: invoke times->MockBehavior
 */
public class MethodBehaviors extends HashMap<String, Map<Integer, MockBehavior>> {

    private String declaredToFake;
    /**
     * 需要mock的方法列表
     */
    @Getter
    private final Set<MethodId> methodIds = new HashSet<>();

    MethodBehaviors(Class declaredToFake) {
        this.declaredToFake = TypeUtility.classPath(declaredToFake);
    }

    public void addMockBehavior(String realClass, String name, String desc, int index, MockBehavior behavior) {
        String methodId = this.initMeta(realClass, name, desc);
        this.get(methodId).put(index, behavior);
    }


    private String initMeta(String realClass, String name, String desc) {
        MethodId meta = new MethodId(this.declaredToFake, realClass, name, desc);
        this.methodIds.add(meta);
        if (!this.containsKey(meta.methodDesc)) {
            this.put(meta.methodDesc, new HashMap<>());
        }
        return meta.methodDesc;
    }
}